﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace VIA.SiMoJi.Domain
{
    /// <summary>
    /// 熵基人脸识别考勤机
    /// </summary>
    public interface IZKTEcoFace
    {
        event EventHandler<ZKTEcoFaceInitializeEvents> InitializeEvents;
        event EventHandler<ZKTEcoFaceLoginEvents> LoginLoginEvent;
        event EventHandler<ZKTEcoFaceOperationEvents> OperationEvent;
        event EventHandler<ZKTEcoFaceUploadUserInfoEvents> UploadUserInfoEvent;
        event EventHandler<ZKTEcoFaceHeartbeatEvents> HeartbeatEvent;
        void Start(string ip, int port);
        void Stop();
    }


    public class ZKTEcoFace : IZKTEcoFace
    {
        public event EventHandler<ZKTEcoFaceInitializeEvents> InitializeEvents;
        public event EventHandler<ZKTEcoFaceLoginEvents> LoginLoginEvent;
        public event EventHandler<ZKTEcoFaceOperationEvents> OperationEvent;
        public event EventHandler<ZKTEcoFaceUploadUserInfoEvents> UploadUserInfoEvent;
        public event EventHandler<ZKTEcoFaceHeartbeatEvents> HeartbeatEvent;

        HttpListener _listener;
        public string IpAddress { get; private set; }
        public int Port { get; private set; }
        public ZKTEcoFace() { }
        public bool IsStarted { get; private set; }

        public void Start(string ipAddress, int port)
        {
            IpAddress = ipAddress;
            Port = port;
            _listener = new HttpListener();
            _listener.Prefixes.Add($"http://{IpAddress}:{Port}/");
            _listener.Start();
            Thread threadWatch = new Thread(WatchConnecting);
            threadWatch.IsBackground = true;
            threadWatch.Start();
            IsStarted = true;
            Task.Factory.StartNew(() => CustomerRequest(), TaskCreationOptions.LongRunning);
        }
        public void Stop()
        {
            _listener.Stop();
            IsStarted = false;
        }
        void WatchConnecting()
        {
            while (IsStarted)
            {
                HttpListenerContext context = _listener.GetContext();
                // 获取请求对象和响应对象
                HttpListenerRequest request = context.Request;
                HttpListenerResponse response = context.Response;
                string requestBody = string.Empty;
                string requestMethod = context.Request.HttpMethod;
                string requestUrl = context.Request.Url.ToString();
                using (var reader = new StreamReader(context.Request.InputStream, Encoding.GetEncoding("GB2312")))
                {
                    requestBody = reader.ReadToEnd();
                }
                Console.WriteLine("Received {0} request for {1} with body: {2}", requestMethod, requestUrl, requestBody);
                string responseString = "OK";
                requests.Add(new ZKTEcoRequest(requestMethod, requestUrl, requestBody));
                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
                // 设置响应头和响应内容
                response.ContentLength64 = buffer.Length;
                //response.ContentType = "text/plain";
                response.ContentType = "text/html";
                response.OutputStream.Write(buffer, 0, buffer.Length);
                // 关闭响应连接
                response.Close();
            }
        }
        BlockingCollection<ZKTEcoRequest> requests = new BlockingCollection<ZKTEcoRequest>();
        void CustomerRequest()
        {
            foreach (var request in requests.GetConsumingEnumerable())
            {
                if (request.Method.Contains("GET") && request.Url.Contains("language"))
                {
                    InitializeEvents?.Invoke(this, new ZKTEcoFaceInitializeEvents() { Request = new InitializeRequest(request) });
                }
                else if (request.Url.Contains("getrequest"))
                {
                    HeartbeatEvent?.Invoke(this, new ZKTEcoFaceHeartbeatEvents() { Request = new HeartbeatRequest(request) });
                }
                else if (request.Url.Contains("ATTLOG"))
                {
                    LoginLoginEvent?.Invoke(this, new ZKTEcoFaceLoginEvents() { Request = new LoginRequest(request) });
                }
                else if (request.Url.Contains("OPERLOG") && request.Body.Contains("OPLOG"))
                {
                    OperationEvent?.Invoke(this, new ZKTEcoFaceOperationEvents() { Request = new OperatingRequest(request) });
                }
                else if (request.Url.Contains("OPERLOG") && request.Body.Contains("USER PIN"))
                {
                    UploadUserInfoEvent?.Invoke(this, new ZKTEcoFaceUploadUserInfoEvents() { Request = new UploadUserInfoRequest(request) });
                }
            }
        }
    }
}
